package com.farm.wda;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.nio.channels.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.farm.wda.impl.WdaAppImpl;
import com.farm.wda.inter.WdaAppInter;
import com.farm.wda.service.FileKeyCoderInter;
import com.farm.wda.service.impl.FileKeyCoderImpl;
import com.farm.wda.util.AppConfig;

/**
 * 服务门面类
 * 
 * @author macplus
 *
 */
public class Beanfactory {

	public static String WEB_DIR;
	public static String WEB_URL;
	private static boolean isstart;
	private static final Logger log = Logger.getLogger(Beanfactory.class);
	private static WdaAppInter wda = null;

	/**
	 * 获得转换服务
	 * 
	 * @return
	 */
	public static WdaAppInter getWdaAppImpl() {
		try {
			return new WdaAppImpl();
		} catch (RemoteException e) {
			log.error(e + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 获得文件命名文件地址服务
	 * 
	 * @return
	 */
	public static FileKeyCoderInter getFileKeyCoderImpl() {
		return new FileKeyCoderImpl();
	}

	/**
	 * openoffce服务是否启动
	 * 
	 * @return
	 */
	public static boolean isStartByOpenofficeServer() {
		long outTime = 3000;
		ExecutorService executor = Executors.newSingleThreadExecutor();
		FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>() {
			@Override
			public Boolean call() throws Exception {
				boolean isStart = false;
				OpenOfficeConnection con = new SocketOpenOfficeConnection(AppConfig.getString("config.openoffice.host"),
						Integer.valueOf(AppConfig.getString("config.openoffice.port")));
				try {
					con.connect();
					if (con.isConnected()) {
						isStart = true;
					} else {
						isStart = false;
					}
				} catch (ConnectException e1) {
					isStart = false;
				} finally {
					if (isStart) {
						con.disconnect();
					}
				}
				return isStart;
			}
		});
		executor.execute(future);
		boolean isStart = false;
		try {
			// 在一定时间内执行该任务
			isStart = future.get(outTime, TimeUnit.MILLISECONDS); // 取得结果，同时设置超时执行时间为5秒。同样可以用future.get()，不设置执行超时时间取得结果
			log.info("WDA[OpenOfficeSever]------------ state:" + isStart);
		} catch (Exception e) {
			log.info("WDA[OpenOfficeSever]------------ Error:" + e.getClass() + ":" + e.getMessage());
			future.cancel(true);
		} finally {
			executor.shutdown();
		}
		return isStart;
	}

	/**
	 * 启动office转换服务(相当于重启，先杀掉进程再启动进程)
	 */
	public static void startOpenOfficeServer() {
		Runtime runtime = Runtime.getRuntime();
		try {
			log.info("run[kill]---openoffice service...");
			String cmd = AppConfig.getString("config.server.openoffice.kill.cmd");
			log.info(cmd);
			Process proc1 = null;
			if (AppConfig.getString("config.server.os.islinux").toUpperCase().equals("TRUE")) {
				String[] linuxcmd = new String[] { "sh", "-c", cmd };
				log.info("is linux...");
				proc1 = runtime.exec(linuxcmd);
			} else {
				proc1 = runtime.exec(cmd);
			}
			BufferedReader br = new BufferedReader(
					new InputStreamReader(proc1.getInputStream(), AppConfig.getString("config.server.os.cmd.encode")));
			String msg = null;
			while ((msg = br.readLine()) != null) {
				log.info(msg);
			}
		} catch (IOException exception) {
			log.error("Error:run[kill]---openoffice service:" + exception.getMessage(), exception);
		}
		try {
			log.info("run[start]---openoffice service...");
			String cmd = AppConfig.getString("config.server.openoffice.start.cmd");
			log.info(cmd);
			if (AppConfig.getString("config.server.os.islinux").toUpperCase().equals("TRUE")) {
				String[] linuxcmd = new String[] { "sh", "-c", cmd };
				log.info("linux环境...");
				runtime.exec(linuxcmd);
			} else {
				runtime.exec(cmd);
			}
		} catch (IOException exception) {
			log.error("Error:run[start]---openoffice service:" + exception.getMessage(), exception);
		}
	}

	/**
	 * 启动rim服务
	 */
	public static void startRmi() {
		try {
			int port = Integer.valueOf(AppConfig.getString("config.rmi.port"));
			String rui = "rmi://127.0.0.1:" + port + "/wda";
			wda = Beanfactory.getWdaAppImpl();
			LocateRegistry.createRegistry(port);
			Naming.rebind(rui, wda);
			log.info("启动RMI服务" + rui);
		} catch (RemoteException e) {
			System.out.println("创建远程对象发生异常！");
			log.error(e + e.getMessage(), e);
		} catch (AlreadyBoundException e) {
			System.out.println("发生重复绑定对象异常！");
			log.error(e + e.getMessage(), e);
		} catch (MalformedURLException e) {
			System.out.println("发生URL畸形异常！");
			log.error(e + e.getMessage(), e);
		}
	}

	/**
	 * 启动转换器
	 */
	public static void statrtConverter() {
		if (isstart == true) {
			return;
		}
		isstart = true;
		Thread t = new Thread(new ConvertFactory());
		t.start();
	}
}
